#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <sys/wait.h>
#include <cstring>

void ChildWrite(int pfd)
{
    // char buffer[1024];
    char ch = 0;
    int cnt = 0;

    while (true)
    {
        // snprintf(buffer, sizeof(buffer), "I am child, I am writeing, My pid id %d, cnt = %d", getpid(), cnt++);
        // write(pfd, buffer, strlen(buffer));
        write(pfd, &ch, 1);
        printf("child: %d\n", cnt++);
        // sleep(1);
        // break;
    }
}

void ParentRead(int pfd)
{
    char buffer[1024] = {0};

    while (true)
    {
        sleep(100);
        ssize_t n = read(pfd, buffer, sizeof(buffer) - 1);
        if (n < 0)
        {
            std::cerr << "read error" << std::endl;
            break;
        }
        else if (n == 0)
        {
            // 子进程关闭写端后，read 返回 0
            std::cout << "n:" << n << std::endl;
            std::cout << "child closed pipe" << std::endl;
            break;
        }
        else
        {
            buffer[n] = '\0';
            std::cout << "Child say: " << buffer << std::endl;
            // sleep(3);
            break;
        }
    }
}
int main()
{
    int pipefd[2];
    // 管道创建：pipefd[0] 是读端，pipefd[1] 是写端
    if (pipe(pipefd) < 0)
    {
        std::cerr << "pipe error" << std::endl;
        return 1;
    }

    std::cout << "pipefd[0] (read end): " << pipefd[0] << std::endl;
    std::cout << "pipefd[1] (write end): " << pipefd[1] << std::endl;

    pid_t id = fork();
    if (id == 0)
    {
        // child
        close(pipefd[0]);
        ChildWrite(pipefd[1]);
        close(pipefd[1]);
        return 0;
    }

    close(pipefd[1]);
    ParentRead(pipefd[0]);
    close(pipefd[0]);

    int status;
    waitpid(id, &status, 0);
    std::cout << "child exited, status: " << status << std::endl;

    return 0;
}